package com.xu.sso.web.controller;

import com.xu.sso.client.filter.LoginFilter;
import com.xu.sso.client.model.UserLoginInfo;
import com.xu.sso.core.exception.SSOException;
import com.xu.sso.core.model.BaseResponse;
import com.xu.sso.db.model.base.App;
import com.xu.sso.db.model.base.AppRole;
import com.xu.sso.db.model.base.Resources;
import com.xu.sso.db.model.base.User;
import com.xu.sso.web.model.request.*;
import com.xu.sso.web.service.AppService;
import com.xu.sso.web.service.PowerService;
import com.xu.sso.web.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@Controller
@RequestMapping("/app")
public class AppController {

    @Autowired
    private AppService appService;
    @Autowired
    private UserService userService;
    @Autowired
    private PowerService powerService;

    @RequestMapping("/toSearch")
    public String toAppSearch(Model model) {
        List<App> list = appService.findAllApp();
        model.addAttribute("appList", list);
        return "app/appList";
    }

    @RequestMapping("/search")
    public String search(Model model, AppSearchRequest searchRequest) {
        List<App> list = appService.findAppList(searchRequest);
        model.addAttribute("appList", list);
        model.addAttribute("req", searchRequest);
        return "app/appList";
    }

    @RequestMapping("/checkAppExist")
    @ResponseBody
    public BaseResponse checkAppExist(String appId) throws SSOException {
        return appService.checkAppExist(appId);
    }

    @RequestMapping("/toAdd")
    public String toAdd() {
        return "app/add";
    }

    @PostMapping("/add")
    @ResponseBody
    public BaseResponse addApp(AddAppRequest appRequest) throws SSOException {
        UserLoginInfo userLoginInfo = LoginFilter.threadLocal.get();
        return appService.createApp(appRequest, userLoginInfo.getUsername());
    }

    @RequestMapping("/deleteApp")
    @ResponseBody
    public BaseResponse deleteApp(String appId) throws SSOException {
        return appService.deleteApp(appId);
    }

    @RequestMapping("/toAppUser")
    public String toAppUser(Model model) {
        UserLoginInfo userLoginInfo = LoginFilter.threadLocal.get();
        List<App> list = appService.findAllAppByLeader(userLoginInfo.getUsername());
        model.addAttribute("appList", list);
        return "/app/appUser";
    }

    @RequestMapping("/selectAppUser")
    public String selectAppUser(Model model, String appId) {
        UserLoginInfo userLoginInfo = LoginFilter.threadLocal.get();
        List<User> users = userService.findAllUserByAppId(appId);
        List<App> apps = appService.findAllAppByLeader(userLoginInfo.getUsername());
        model.addAttribute("appList", apps);
        model.addAttribute("appId", appId);
        model.addAttribute("userList", users);
        return "/app/appUser";
    }

    @RequestMapping("/deleteAppUser")
    @ResponseBody
    public BaseResponse deleteAppUser(String appId, String username) throws SSOException {
        return appService.deleteAppUser(appId, username);
    }

    @RequestMapping("/checkLeader")
    @ResponseBody
    public BaseResponse checkLeader(String appId) throws SSOException {
        UserLoginInfo userLoginInfo = LoginFilter.threadLocal.get();
        return appService.checkLeader(appId, userLoginInfo.getUsername());
    }

    @RequestMapping("/changeStatus")
    @ResponseBody
    public BaseResponse changeStatus(String appId, String status) throws SSOException {
        UserLoginInfo userLoginInfo = LoginFilter.threadLocal.get();
        return appService.changeStatus(appId, status, userLoginInfo.getUsername());
    }

    @RequestMapping("/toChange")
    public String toChange(Model model, String appId) {
        App app = appService.findAppByAppId(appId);
        model.addAttribute("app", app);
        return "app/change";
    }

    @PostMapping("/change")
    @ResponseBody
    public BaseResponse change(ChangeAppRequest appRequest) throws SSOException {
        return appService.changeApp(appRequest);
    }

    @RequestMapping("/toAppPower")
    public String toAppPower(Model model) {
        UserLoginInfo userLoginInfo = LoginFilter.threadLocal.get();
        List<App> list = appService.findAllAppByLeader(userLoginInfo.getUsername());
        model.addAttribute("appList", list);
        return "app/appPower";
    }

    @RequestMapping("/selectAppPower")
    public String selectAppPower(Model model, String appId) {
        UserLoginInfo userLoginInfo = LoginFilter.threadLocal.get();
        List<App> apps = appService.findAllAppByLeader(userLoginInfo.getUsername());
        List<Resources> list = powerService.findAllAppRes(appId);
        model.addAttribute("appList", apps);
        model.addAttribute("appId", appId);
        model.addAttribute("resourcesList", list);
        return "app/appPower";
    }

    @RequestMapping("/toAddResources")
    public String toAddResources(Model model, String appId) {
        model.addAttribute("appId", appId);
        return "app/addPower";
    }

    @RequestMapping("/toUpdateResources")
    public String toUpdateResources(Model model, Integer resId) {
        Resources resources = powerService.findResById(resId);
        model.addAttribute("res", resources);
        return "app/updatePower";
    }

    @RequestMapping("/updateResources")
    @ResponseBody
    public BaseResponse updateResources(Resources resources) throws SSOException {
        return powerService.updateRes(resources);
    }

    @RequestMapping("/deleteResources")
    @ResponseBody
    public BaseResponse deleteResources(Integer resId) throws SSOException {
        return powerService.deleteRes(resId);
    }

    @PostMapping("/addRes")
    @ResponseBody
    public BaseResponse addRes(AddResourcesRequest request) throws SSOException {
        return powerService.addRes(request);
    }

    @RequestMapping("/refreshRedis")
    @ResponseBody
    public BaseResponse refreshRedis(String appId) throws SSOException {
        return powerService.refreshRedis(appId);
    }

    @RequestMapping("/toAppRole")
    public String toAppRole(Model model) {
        UserLoginInfo userLoginInfo = LoginFilter.threadLocal.get();
        List<App> list = appService.findAllAppByLeader(userLoginInfo.getUsername());
        model.addAttribute("appList", list);
        return "app/appRole";
    }

    @RequestMapping("/selectAppRole")
    public String selectAppRole(Model model, String appId) {
        UserLoginInfo userLoginInfo = LoginFilter.threadLocal.get();
        List<App> apps = appService.findAllAppByLeader(userLoginInfo.getUsername());
        List<AppRole> roles = appService.findAppRoles(appId);
        model.addAttribute("appList", apps);
        model.addAttribute("appId", appId);
        model.addAttribute("rolesList", roles);
        return "app/appRole";
    }

    @RequestMapping("/toAddRole")
    public String toAddRole(Model model, String appId) {
        model.addAttribute("appId", appId);
        return "app/addRole";
    }

    @RequestMapping("/checkRoleExist")
    @ResponseBody
    public BaseResponse checkRoleExist(String appId, String roleName) throws SSOException {
        return powerService.checkRoleExist(appId, roleName);
    }

    @PostMapping("/addAppRole")
    @ResponseBody
    public BaseResponse addAppRole(AddRoleRequest request) throws SSOException {
        return powerService.addAppRole(request);
    }

    @RequestMapping("/toUpdateRole")
    public String toUpdateRole(Model model, Integer id) {
        AppRole appRole = powerService.findAppRoleById(id);
        model.addAttribute("role", appRole);
        return "app/updateRole";
    }

    @RequestMapping("/deleteRole")
    @ResponseBody
    public BaseResponse deleteRole(Integer id) throws SSOException {
        return powerService.deleteRoleById(id);
    }

    @RequestMapping("/updateRole")
    @ResponseBody
    public BaseResponse updateRole(AppRole appRole) throws SSOException {
        return powerService.updateRole(appRole);
    }

    @RequestMapping("/changeRoleStatus")
    @ResponseBody
    public BaseResponse changeRoleStatus(Integer id, String status) throws SSOException {
        return powerService.updateRoleStatus(id, status);
    }

    @RequestMapping("/toAddAppUser")
    public String toAddAppUser(Model model, String appId) {
        List<User> inAppUsers = userService.findAllUserByAppId(appId);
        List<User> notInAppUsers = userService.findAllUserNotInApp(appId);
        model.addAttribute("inAppUsers", inAppUsers);
        model.addAttribute("notInAppUsers", notInAppUsers);
        model.addAttribute("appId", appId);
        return "app/addAppUser";
    }

    @RequestMapping("/addAppUser")
    @ResponseBody
    public BaseResponse addAppUser(String appId, String users) throws SSOException {
        return powerService.addAppUser(appId, users);
    }

    @RequestMapping("/toAddAppUserRole")
    public String toAddAppUserRole(Model model, String appId, String username) {
        List<AppRole> inAppRoles = powerService.findInAppUserRole(appId, username);
        List<AppRole> notInAppRoles = powerService.findNotInAppUserRole(appId, username);
        boolean isLeader = appService.isLeader(appId, username);
        model.addAttribute("inAppRoles", inAppRoles);
        model.addAttribute("notInAppRoles", notInAppRoles);
        model.addAttribute("appId", appId);
        model.addAttribute("username", username);
        model.addAttribute("isLeader", isLeader);
        return "app/addAppUserRole";
    }

    @RequestMapping("/addAppUserRole")
    @ResponseBody
    public BaseResponse addAppUserRole(AddUserRoleRequest request) throws SSOException {
        return powerService.addAppUserRole(request);
    }

    @RequestMapping("/toAddResourcesRole")
    public String toAddResourcesRole(Model model, String appId, Integer resId) {
        List<AppRole> inAppRoles = powerService.findInResRole(appId, resId);
        List<AppRole> notInAppRoles = powerService.findNotInResRole(appId, resId);
        model.addAttribute("inAppRoles", inAppRoles);
        model.addAttribute("notInAppRoles", notInAppRoles);
        model.addAttribute("appId", appId);
        model.addAttribute("resId", resId);
        return "app/addResourcesRole";
    }

    @RequestMapping("/addResourcesRole")
    @ResponseBody
    public BaseResponse addResourcesRole(AddResRoleRequest request) throws SSOException {
        return powerService.addResourcesRole(request);
    }

}
